package com.fortune.conf;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.time.LocalDateTime;
import java.util.Date;

/**
 * @program: fortune
 * @description:
 * @author: wwb
 * @create: 2025-04-12 10:16
 */
public class GifCompressorFFmpeg {

    /**
     * 调用FFmpeg压缩GIF文件
     * @param inputPath  输入文件路径
     * @param outputPath 输出文件路径
     * @param scaleRatio 缩放比例（如0.5表示缩小50%）
     */
    public static void compressGifWithFFmpeg(String inputPath,
                                             String outputPath,
                                             double scaleRatio) throws Exception {
        // 生成调色板文件（临时文件）
        String palettePath = "palette.png";

        // 第一步：生成调色板
        ProcessBuilder paletteProcess = new ProcessBuilder(
                "ffmpeg",
                "-i", inputPath,
                "-vf", "palettegen=stats_mode=diff",
                "-y",  // 覆盖已存在文件
                palettePath
        );
        executeCommand(paletteProcess, "生成调色板失败");

        // 第二步：压缩时保留时间参数
        double originalFps = getGifFrameRate(inputPath);

        ProcessBuilder compressProcess = new ProcessBuilder(
                "ffmpeg",
                "-i", inputPath,
                "-i", palettePath,
                "-filter_complex", String.format(
                "[0:v] scale=iw*%s:ih*%s [scaled]; [scaled][1:v] paletteuse=dither=bayer",
                scaleRatio, scaleRatio
        ),
                "-vsync", "0",
                "-enc_time_base", "-1",
                "-r", String.valueOf(originalFps), // 动态设置原帧率
                "-y",
                outputPath
        );

        executeCommand(compressProcess, "压缩GIF失败");

        // 清理临时调色板文件
        new File(palettePath).delete();
    }


    // 使用FFprobe获取原GIF帧率
    public static double getGifFrameRate(String inputPath) throws Exception {
        ProcessBuilder probeProcess = new ProcessBuilder(
                "ffprobe",
                "-v", "error",
                "-select_streams", "v:0",
                "-show_entries", "stream=avg_frame_rate",
                "-of", "default=noprint_wrappers=1:nokey=1",
                inputPath
        );

        Process process = probeProcess.start();
        try (BufferedReader br = new BufferedReader(
                new InputStreamReader(process.getInputStream()))) {
            String frameRateStr = br.readLine();
            String[] parts = frameRateStr.split("/");
            return Double.parseDouble(parts[0]) / Double.parseDouble(parts[1]);
        }
    }

    public static void superCompressGif(String inputPath,
                                        String outputPath,
                                        double scaleRatio) throws Exception {
        // 生成调色板（简化参数确保兼容性）
        ProcessBuilder paletteProcess = new ProcessBuilder(
                "ffmpeg",
                "-i", inputPath,
                "-vf", "palettegen=max_colors=64",
                "-y",
                "palette.png"
        );
        executeCommand(paletteProcess, "调色板生成失败");

        // 构建兼容性滤镜链（关键修正）
        String filterChain = String.format(
                "[0:v]scale=iw*%s:ih*%s:flags=lanczos[scaled];" +  // 指定高质量缩放算法
                        "[scaled]split[base][anal];" +                     // 分流处理
                        "[anal]mpdecimate=hi=64:lo=32:frac=0.1[decimated];" +  // 独立动态删帧流
                        "[base][decimated]blend=all_mode=average[merged];" +   // 混合原始和删帧流
                        "[merged][1:v]paletteuse=dither=bayer:bayer_scale=4",  // 最终输出
                scaleRatio, scaleRatio
        );

        ProcessBuilder compressProcess = new ProcessBuilder(
                "ffmpeg",
                "-i", inputPath,
                "-i", "palette.png",
                "-filter_complex", filterChain,
                "-vsync", "0",
                "-compression_level", "9",  // 启用LZW最高压缩
                "-y",
                outputPath
        );
        executeCommand(compressProcess, "深度压缩失败");

        new File("palette.png").delete();
    }
    public static void extremeCompress(String inputPath, String outputPath) throws Exception {
        // 三步式处理确保兼容性
        String tempPath1 = "temp1.gif";
        String tempPath2 = "temp2.gif";

        // 第一步：尺寸缩减和帧率控制
        ProcessBuilder step1 = new ProcessBuilder(
                "ffmpeg",
                "-i", inputPath,
                "-vf", "scale=iw*1:ih*1:flags=area,fps=10", // 缩小50% + 帧率降至10
                "-compression_level", "9",
                "-y",
                tempPath1
        );
        executeCommand(step1, "第一阶段压缩失败");

        // 第二步：颜色深度压榨
        ProcessBuilder step2 = new ProcessBuilder(
                "ffmpeg",
                "-i", tempPath1,
                "-vf", "palettegen=max_colors=32", // 强制使用32色
                "-y",
                "palette.png"
        );
        executeCommand(step2, "调色板生成失败");

        // 第三步：最终压缩
        ProcessBuilder step3 = new ProcessBuilder(
                "ffmpeg",
                "-i", tempPath1,
                "-i", "palette.png",
                "-filter_complex", "[0][1]paletteuse=dither=none:diff_mode=rectangle", // 禁用抖动
                "-gifflags", "+transdiff", // 启用透明差异优化
                "-compression_level", "12",
                "-y",
                outputPath
        );
        executeCommand(step3, "最终压缩失败");

        // 清理临时文件
        new File(tempPath1).delete();
        new File(tempPath2).delete();
        new File("palette.png").delete();
    }
    /**
     * 执行命令行并处理错误
     */
    private static void executeCommand(ProcessBuilder processBuilder, String errorMsg)
            throws IOException, InterruptedException {
        processBuilder.redirectErrorStream(true);
        Process process = processBuilder.start();

        // 打印命令行输出（可选调试）
        try (BufferedReader reader = new BufferedReader(
                new InputStreamReader(process.getInputStream()))) {
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line); // 可注释掉以静默运行
            }
        }

        int exitCode = process.waitFor();
        if (exitCode != 0) {
            throw new RuntimeException(errorMsg + " (Exit code: " + exitCode + ")");
        }
    }

    // 使用示例
    public static void main(String[] args) {
        try {
            extremeCompress(
                    "D:\\wwb\\1\\fc_image\\uncompressed\\2025\\4\\29\\9a8903befcea4911b68deca9751a5dc2.gif",
                    "D:\\tmp\\1\\121113123.gif"
            );
            System.out.println("GIF压缩完成！");
        } catch (Exception e) {
            System.err.println("压缩失败: " + e.getMessage());
        }




////        String url = "https://sapi.k780.com/?app=finance.gold_price&goldid=1051&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json";
//        String url = "https://www.sge.com.cn/graph/quotations";
//        String resutUrlStr = HttpUtil.get(url);
//        JSONObject jsonObject = JSONObject.parseObject(resutUrlStr);
//        String maxStr = jsonObject.getString("max");
//        String minStr = jsonObject.getString("min");
//        String delaystr = jsonObject.getString("delaystr");
//
//        JSONArray times = jsonObject.getJSONArray("times");
//        JSONArray data = jsonObject.getJSONArray("data");
//
//        LocalDateTime now = LocalDateTime.now();
//        LocalDateTime fourMinutesEarlier = now.minusMinutes(2);
//
//
//        int hour = fourMinutesEarlier.getHour();
//        int minute = fourMinutesEarlier.getMinute();
//        String hourStr = ""+hour,minuteStr=""+minute;
//        if (hour < 10) {
//            hourStr = "0" + hour;
//        }
//
//        if (minute < 10) {
//            minuteStr = "0" + minute;
//        }
//
//        String timeStr = hourStr + ":" + minuteStr;
//        int position = findPosition(times, timeStr);
//
//
//        System.out.println("timeStr:"+timeStr);
//        System.out.println(data.stream().toArray());
//
//        System.out.println("当前："+data.get(position));
//        System.out.println("最小："+minStr);
//        System.out.println("最大："+maxStr);
//        System.out.println("时间："+delaystr);

    }

    public static int findPosition(JSONArray array, String target) {
        for (int i = 0; i < array.size(); i++) {
            if (array.get(i).toString().equals(target)) {
                return i; // 返回找到的位置
            }
        }
        return -1; // 如果未找到，返回-1
    }
}